package cn.good.yan.service.t7;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * 7. 原子类
 * AtomicIntegerFieldUpdater ， 原子类 ，对于一个类的，某个字段（需要保持原子性）某个方法，对该值操作
 *
 * @author shengren.yan
 * @create 2024-04-02
 */
public class AtomicDemo4 {

    public static void main(String[] args) throws InterruptedException {
        // 资源类
        BankAccount bankAccount = new BankAccount();
        // 线程工具 - 启动10个线程，一起对资源类的某个字段money，进行累加
        CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                try {
                    for (int j = 1; j <= 1000; j++) {
                        // 原版的 + synchronized
                        bankAccount.add();
                        // 新版的 + 使用：AtomicIntegerFieldUpdater
                        bankAccount.transMoney(bankAccount);
                    }
                } finally {
                    countDownLatch.countDown();
                }
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "\t" + "获取累计的总和 - result: " + bankAccount.money);
    }

}

// 资源类
class BankAccount {
    String bankName = "CCB";
    // 更新的对象属性必须使用 public volatile 修饰符。
    public volatile int money = 0;//钱数

    // 原版 ， 下面是新版
    public synchronized void add() {
        money++;
    }

    // 因为对象的属性修改类型原子类都是抽象类，所以每次使用都必须
    // 参数：1.哪个实体类、2，哪个字段
    AtomicIntegerFieldUpdater<BankAccount> fieldUpdater =
            AtomicIntegerFieldUpdater.newUpdater(BankAccount.class, "money");

    // 不加synchronized，保证高性能原子性，局部微创小手术
    public void transMoney(BankAccount bankAccount) {
        // 原子类的 +1 操作
        fieldUpdater.getAndIncrement(bankAccount);
    }

}